#pragma once

#include <algorithm>
#include <exception>
#include <vector>

#include "glare.d3d11.Prerequisites.h"
#include "glare.core.Driver.h"
#include "glare.core.DriverCapabilities.h"

namespace Glare {

	class D3D11Driver : public Driver
	{
	public : static string Name;

	public : D3D11Driver();
	public : virtual ~D3D11Driver();

	public : virtual std::string& GetName() const;

	public : virtual GpuResourceFactory* GetGpuResourceFactory() const;
	public : virtual ShaderFactory* GetShaderFactory() const;
	public : virtual DrawStateFactory* GetDrawStateFactory() const;

	public : virtual RenderWindow* CreateRenderWindow(PlatformWindow* platform_window);
	public : virtual void DestroyRenderWindow(RenderWindow* render_window);

	public : virtual const DriverStage::Type GetSupportedStages() const;
	public : virtual const DriverCapabilities& GetCapabilities() const;

	public : virtual DrawContext* GetImmediateDrawContext() const;
	public : virtual DrawContext* CreateDrawContext();
	public : virtual void DestroyDrawContext(DrawContext* draw_context);

	// <Internal methods>
	public : ID3D11Device* GetD3DDevice() const;
	public : ID3D11DeviceContext* GetD3DImmediateContext() const;

	public : IDXGIDevice* GetDXGIDevice() const;
	public : IDXGIAdapter* GetDXGIAdapter() const;
	public : IDXGIFactory* GetDXGIFactory() const;
	// </Internal methods>
			 
	public : IDXGIAdapter* PrimaryGpu;
	public : IDXGIAdapter* SecondaryGpu;
	public : IDXGIAdapter* TertiaryGpu;
	public : IDXGIAdapter* QuaternaryGpu;

	public : IDXGIOutput* PrimaryMonitor;
	public : IDXGIOutput* SecondaryMonitor;
	public : IDXGIOutput* TertiaryMonitor;
	public : IDXGIOutput* QuaternaryMonitor;

	public : D3D11_FEATURE_DATA_THREADING ThreadingSupport;

	private : DriverCapabilities _driver_caps;

	private : ID3D11Device* _d3d_device;
	private : ID3D11DeviceContext* _d3d_immediate_context;

	private : IDXGIDevice* _dxgi_device;
	private : IDXGIAdapter* _dxgi_adapter;
	private : IDXGIFactory* _dxgi_factory;

	private : D3D11GpuResourceFactory* _gpu_resources;
	private : D3D11ShaderFactory* _gpu_shaders;
	private : D3D11DrawStateFactory* _draw_states;

	private : D3D11DrawContext* _immediate_draw_context;
	};
}
